package com.tian.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.tian.dto.charger.*;
import com.tian.entity.*;
import com.tian.enums.ChargerStatusEnum;
import com.tian.enums.PayStatusEnum;
import com.tian.mapper.ChargeGunMapper;
import com.tian.mapper.ChargerMapper;
import com.tian.mapper.ChargerRecordMapper;
import com.tian.mqtt.enums.MqttTopicEnum;
import com.tian.mqtt.message.ChargerStopPublishMessage;
import com.tian.mqtt.message.ChargerStopSubscribeMessage;
import com.tian.service.ChargerRecordService;
import com.tian.util.CommonResult;
import com.tian.util.DateTimeUtil;
import com.tian.util.StringUtil;
import com.tian.util.UserCacheUtil;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * @author tianwc  公众号：java后端技术全栈、面试专栏
 * @version 1.0.0
 * 2023年11月01日 11:19
 * 在线刷题 1200+题和1000+篇干货文章：<a href="https://woaijava.cc/">博客地址</a>
 * <p>
 * 充电记录
 */
@Slf4j
@Service
public class ChargerRecordServiceImpl implements ChargerRecordService {
    @Resource
    private MqttClient client4Publish;
    @Resource
    private ChargerRecordMapper chargerRecordMapper;
    @Resource
    private ChargeGunMapper chargeGunMapper;
    @Resource
    private ChargerMapper chargerMapper;

    @Override
    public void doStartCharge(ChargerRecordAddReqDto chargerRecordAddReqDto) {
        if (StringUtil.isEmpty(chargerRecordAddReqDto.getGunNo()) || chargerRecordAddReqDto.getUserId() == null) {
            log.error("接受到消息内容为空，msg={}", chargerRecordAddReqDto);
            return;
        }
        ChargeGun chargeGun = chargeGunMapper.selectByGunNo(chargerRecordAddReqDto.getGunNo());
        if (chargeGun == null) {
            log.error("接受到消息中gunNo有误，msg={}", chargerRecordAddReqDto);
            return;
        }
        Charger charger = chargerMapper.selectByPrimaryKey(chargeGun.getChargerId());

        ChargerRecord chargerRecord = new ChargerRecord();
        chargerRecord.setChargerGunId(chargeGun.getId());
        chargerRecord.setUserId(chargerRecordAddReqDto.getUserId());
        chargerRecord.setPayStatus(PayStatusEnum.INIT.getPayStatus());
        chargerRecord.setPrice(charger.getPrice());
        chargerRecord.setStartTime(DateUtil.parseDateTime(chargerRecordAddReqDto.getCreatTime()));
        chargerRecord.setQuantity(BigDecimal.ZERO);
        chargerRecord.setChargeStatus(ChargerStatusEnum.CHARGEING.getChargerStatus());
        chargerRecordMapper.insert(chargerRecord);
    }

    @Override
    public CommonResult<ChargerRecordUpdateRespDto> readyStopCharge(ChargerRecordUpdateReqDto chargerRecordUpdateReqDto) {
        Integer id = chargerRecordUpdateReqDto.getId();
        ChargerRecord chargerRecord = chargerRecordMapper.selectByPrimaryKey(id);

        User user = UserCacheUtil.getUser();

        ChargeGun chargeGun = chargeGunMapper.selectByPrimaryKey(chargerRecord.getChargerGunId());

        ChargerStopPublishMessage chargerStopMessage = new ChargerStopPublishMessage();
        chargerStopMessage.setName(chargeGun.getName());
        chargerStopMessage.setUserId(user.getId());
        chargerStopMessage.setGunNo(chargeGun.getGunNo());
        MqttMessage message = new MqttMessage();
        message.setQos(0);
        message.setPayload(JSON.toJSONString(chargerStopMessage).getBytes());
        try {
            //发送指令  充电结，设备那边根据发过去的指令进行充电结束，再发充电结束指令 回  系统里
            client4Publish.publish(MqttTopicEnum.CHARGER_STOP_CHARGER_GUN.getTopicName(), message);
        } catch (MqttException e) {
            throw new RuntimeException(e);
        }

        return CommonResult.success();
    }

    @Override
    public void doStopCharge(ChargerStopSubscribeMessage chargerStopSubscribeMessage) {
        ChargeGun chargeGun = chargeGunMapper.selectByGunNo(chargerStopSubscribeMessage.getGunNo());

        Charger charger = chargerMapper.selectByPrimaryKey(chargeGun.getChargerId());

        ChargerRecord chargerRecord = chargerRecordMapper.selectByChargeGunId(chargeGun.getId());

        Date endTime = DateTimeUtil.parseDate(chargerStopSubscribeMessage.getEndTime(), DateTimeUtil.DATE_TIME_FORMAT);

        BigDecimal price = charger.getPrice();
        //如果设备端无法计算电量度数，那就使用功率乘以  (结束时间-开始时间) 分钟单位，再除以60.
        BigDecimal quantity = chargerStopSubscribeMessage.getQuantity();

        BigDecimal money = price.multiply(quantity);

        chargerRecord.setMoney(money);
        chargerRecord.setEndTime(endTime);
        chargerRecord.setQuantity(quantity);
        chargerRecord.setChargeStatus(ChargerStatusEnum.CHARGER_FINISH.getChargerStatus());
        chargerRecordMapper.updateByPrimaryKey(chargerRecord);
    }

    @Override
    public CommonResult<ChargerRecordRespDto> selectById(Integer id) {
        ChargerRecord chargerRecord = chargerRecordMapper.selectByPrimaryKey(id);
        ChargerRecordRespDto chargerRecordRespDto = ChargerRecordConvert.convert4SelectById(chargerRecord);
        return CommonResult.success(chargerRecordRespDto);
    }

    @Override
    public CommonResult<ChargerRecordPageRespDto> page(ChargerRecordPageReqDto chargerRecordPageReqDto) {
        int count = chargerRecordMapper.count(chargerRecordPageReqDto);
        if (count == 0) {
            return CommonResult.success();
        }
        List<ChargerRecord> chargerRecordList = chargerRecordMapper.page(chargerRecordPageReqDto);
        ChargerRecordPageRespDto chargerRecordPageRespDto = ChargerRecordConvert.convert4Page(chargerRecordList);
        return CommonResult.success(chargerRecordPageRespDto);
    }
}